//
// Created by 19594 on 25-10-27.
//

#include "BMP280.h"
#include "i2c.h"
typedef struct {
    uint16_t digT1;
    int16_t digT2;
    int16_t digT3;
    uint16_t digP1;
    int16_t digP2;
    int16_t digP3;
    int16_t digP4;
    int16_t digP5;
    int16_t digP6;
    int16_t digP7;
    int16_t digP8;
    int16_t digP9;
    int32_t t_fine;
}bmp280_cali;
bmp280_cali cali;
int32_t t_fine;
void BMP280_WriteReg(uint8_t ADDR, uint8_t value) {
    HAL_I2C_Mem_Write(&hi2c1,0xee,ADDR,I2C_MEMADD_SIZE_8BIT,&value,1,100);
}
uint8_t BMP280_ReadReg(uint8_t ADDR) {
    uint8_t data;
    HAL_I2C_Mem_Read(&hi2c1,0xee,ADDR,I2C_MEMADD_SIZE_8BIT,&data,1,100);
    return data;
}
void BMP280_WriteRegs(uint8_t ADDR, uint8_t *DataArray, uint8_t count) {
    HAL_I2C_Mem_Write(&hi2c1,0xee,ADDR,I2C_MEMADD_SIZE_8BIT,DataArray,count,100);
}
void BMP280_ReadRegs(uint8_t ADDR, uint8_t *DataArray, uint8_t count) {
    HAL_I2C_Mem_Read(&hi2c1,0xee,ADDR,I2C_MEMADD_SIZE_8BIT,DataArray,count,100);
}
void BMP280_GetCali() {
    uint8_t data[24];

    BMP280_ReadRegs(0x88,data,24);
    cali.digT1 = (data[1]<<8)|data[0];
    cali.digT2 = (data[3]<<8)|data[2];
    cali.digT3 = (data[5]<<8)|data[4];
    cali.digP1 = (data[7]<<8)|data[6];
    cali.digP2 = (data[9]<<8)|data[8];
    cali.digP3 = (data[11]<<8)|data[10];
    cali.digP4 = (data[13]<<8)|data[12];
    cali.digP5 = (data[15]<<8)|data[14];
    cali.digP6 = (data[17]<<8)|data[16];
    cali.digP7 = (data[19]<<8)|data[18];
    cali.digP8 = (data[21]<<8)|data[20];
    cali.digP9 = (data[23]<<8)|data[22];
}
int32_t BMP280_GetTemp() {
    int32_t var1,var2,adc_T,T;
    uint8_t Buf[3];
    BMP280_ReadRegs(BMP280_TEMPERATURE_MSB_REG,Buf,3);
    adc_T = (int32_t)(((uint32_t)Buf[0] << 12) | ((uint32_t)Buf[1] << 4) | ((uint32_t)Buf[2] >> 4));
    // 温度补偿计算（根据Bosch官方算法）
    var1 = ((((adc_T >> 3) - ((int32_t)cali.digT1 << 1))) * ((int32_t)cali.digT2)) >> 11;
    var2 = (((((adc_T >> 4) - ((int32_t)cali.digT1)) * ((adc_T >> 4) - ((int32_t)cali.digT1))) >> 12) * ((int32_t)cali.digT3)) >> 14;
    t_fine=var1+var2;
    T=(t_fine*5+128)>>8;
    return T;
}
uint32_t BMP280_GetPressure() {
    int64_t var1,var2,P;
    uint8_t Buf[3];
    int32_t adc_P;
    BMP280_ReadRegs(BMP280_PRESSURE_MSB_REG,Buf,3);
    adc_P = (int32_t)(((uint32_t)Buf[0] << 12) | ((uint32_t)Buf[1] << 4) | ((uint32_t)Buf[2] >> 4));
    var1=((int64_t)t_fine)-12800;
    var2=var1*var1*((int64_t)cali.digP6);
    var2=var2+((var1*(int64_t)cali.digP5)<<17);
    var2=var2+(((int64_t)cali.digP4)<<35);
    var1=((var1*var1*(int64_t)cali.digP3)>>8)+((var1*(int64_t)cali.digP2)<<12);
    var1=((((int64_t)1)<<47)+var1)*((int64_t)cali.digP1)>>33;
    if (var1==0) {
        return 0;
    }
    P=1048576-adc_P;
    P=(((P<<31)-var2)*3125)/var1;
    var1=(((int64_t)cali.digP9)*(P>>13))>>25;
    var2=(((int64_t)cali.digP8)*P)>>19;
    P=((P+var1+var2)>>8)+(((int64_t)cali.digP7)<<4);
    return (uint32_t)P;
}
void BMP280_Init() {
    BMP280_WriteReg(BMP280_RESET_REG,0xb6);
    BMP280_WriteReg(BMP280_CTRLMEAS_REG,0xff);
    BMP280_WriteReg(BMP280_CONFIG_REG,0x00);
}